express = require "express"
router = express.Router()
{ requiresLogin,  isAdvertiserAndGet} = require '../middlewares/authorization'

# tablestore依赖
OtsUtil = require '../utils/ots_util'
OtsClient = OtsUtil.getOtsClient()
TableStore = require 'tablestore'
Long = TableStore.Long
l = console.log


# 测试get接口
# url= http://localhost:6999/v2/ts/getCount?day=6
router.get '/getCount',
  requiresLogin
  isAdvertiserAndGet
  (req,res) ->
    {day} = req.query
    ownerId = req.user._id

    end = Math.floor(Date.now()/1000)
    start = end - 8.64e4*(day || 14)
    
    skey = [{ "own": ownerId},{ "type": 'win' },{ "ts": Long.fromNumber(end) },{ "bid": '*' }]
    ekey = [{ "own": ownerId},{ "type": 'win' },{ "ts": Long.fromNumber(start) },{ "bid": '*' }]
    # params = getParams(['status','bf','ac','nc'],[{status:10}],'dsp_bids','FORWARD',skey,ekey)
    params = getParams(['nc','status'],[{status:0}],'dsp_bids','BACKWARD',skey,ekey)
    l(params)
    getAll params,Infinity,addNc,(err,data) ->
      res.send({code:1,msg:err}) if err
      res.send({code:0,data:data})
    

    # getAll params,1e3,0,(err,data) ->
    #   res.send({code:1,msg:err}) if err
    #   res.send({code:0,data:data})


# 测试post接口
# url   http://localhost:6999/v2/ts/getCount
router.post '/getCount',
  requiresLogin
  isAdvertiserAndGet
  (req,res) ->
    {stime,etime,limit,status,algorithm,cols} = req.body
    cols = cols.split(',')
    ownerId = req.user._id

    skey = [{ "own": ownerId},{ "type": 'win' },{ "ts": Long.fromNumber(etime) },{ "bid": '*' }]
    ekey = [{ "own": ownerId},{ "type": 'win' },{ "ts": Long.fromNumber(stime) },{ "bid": '*' }]
    params = getParams(cols,[{status:+status}],'dsp_bids','BACKWARD',skey,ekey)
    l(params)
    getAll params,limit,eval(algorithm),(err,data) ->
      res.send({code:1,msg:err}) if err
      res.send({code:0,data:data})




# nc累加算法
addNc = (result, data) ->
  result = {nc:0,length:0} if Object.prototype.toString.call(result) isnt "[object Object]"
  for v in data
    result.nc += v.nc
  result.length += data.length
  data = []
  l(result)
  return result



# 按条件查询ots所有数据
# params 查询参数
# limit 获取前几条 默认1万条
# algorithm 选填 数据处理算法函数 可以拿到resultRows ,dispose两个变量处理
# cb callback
getAll = (params,limit=1e4,algorithm,cb) ->
    
  nums = 0        # 循环次数
  resultRows = [] # 数据缓存
  getRange = () ->
    OtsClient.getRange params, (err, data) -> 
      if (err) 
        console.log('error:', err)
        cb(err)
        resultRows = []
        return 

      dispose = []   # 建立数据转换数组
      # 遍历阶段数据
      for v in data.rows
        middle = {}

        # 遍历属性数据，格式化到middle对象
        for v1 in v.attributes
          middle[v1.columnName] = v1.columnValue
        dispose.push(middle)
      

      resultRows = if algorithm then algorithm(resultRows,dispose) else resultRows.concat(dispose)    # 默认阶段数据追加到缓存，有其他算法执行其他算法
      console.log(++nums,'--',resultRows.length)                                                      # 打印次数日志   请求次数 -- 缓存数据长度

      #如果data.next_start_primary_key不为空，说明需要继续读取
      if resultRows.length >= limit
        cb(null,resultRows)
      else if data.next_start_primary_key 
        params.inclusiveStartPrimaryKey = [
          { "own": data.next_start_primary_key[0].value },
          { "type": data.next_start_primary_key[1].value },
          { "ts": data.next_start_primary_key[2].value },
          { "bid": data.next_start_primary_key[3].value }
        ]
        getRange() 
      else
        cb(null,resultRows)
  getRange()


# 获取ots参数函数，主要用于dsp_bids表，别的调用要细看下行不行
# cols 需要筛选的列
# filter 属性列字段值筛选,需要在cols把需要过滤的字段选择出来，否则filter不生效
# skey 范围查询开始的联合主键
# ekey 范围查询结束的联合主键
# 例子 cols=['status'],filter=[{status:10}],tabName='dsp_bids',dit='FORWARD'
getParams = (cols,filter,tabName='dsp_bids',dit='FORWARD',skey,ekey) ->

  params = 
    tableName: tabName,
    direction: dit
  params.inclusiveStartPrimaryKey = skey if skey
  params.exclusiveEndPrimaryKey = ekey if skey
  params.columnsToGet = cols if cols

  condition = new TableStore.CompositeCondition(TableStore.LogicalOperator.AND)
  params.columnFilter = condition if filter
  for v1 in filter
    for k,v of v1
      l(k,v)
      condition.addSubCondition(new TableStore.SingleColumnCondition(k, v, TableStore.ComparatorType.EQUAL))
      condition.addSubCondition(new TableStore.SingleColumnCondition(k, v, TableStore.ComparatorType.EQUAL)) if filter.length is 1
  
  return params

# params = 
#   tableName: "dsp_bids",
#   direction: TableStore.Direction.FORWARD
#   inclusiveStartPrimaryKey: [{ "own": ownerId},{ "type": 'win' },{ "ts": Long.fromNumber(start) },{ "bid": '*' }]
#   exclusiveEndPrimaryKy: [{ "own": ownerId},{ "type": 'win' },{ "ts": Long.fromNumber(end) },{ "bid": '*' }]

# columnsToGet: ['status']
# condition = new TableStore.CompositeCondition(TableStore.LogicalOperator.NOT)
# condition.addSubCondition(new TableStore.SingleColumnCondition('status', 10, TableStore.ComparatorType.EQUAL))
# params.columnFilter = condition


# tablestore  params 参数一览  
look =   
  table_name : '表名，字符串类型，必填参数'
  direction : '数据库查询扫描方向，字符串类型，必填参数'
  inclusive_start_primary_key : '范围查询起始主键， getRange 范围查询必填参数，对象数组类型，必须填写所有主键，.为单字符通配符，*为多字符通配符'
  exclusive_end_primary_key : '范围查询结束主键， getRange 范围查询必填参数，对象数组类型，必须填写所有主键，.为单字符通配符，*为多字符通配符'
  maxVersions : "整形，默认1"
  primaryKey : "主键列查询，map[]"
  columnFilter : "属性列条件查询，map[]"
  limit : "和sql limit关键字一样"
  timeRange : "数据范围"
  startColumn : "指定范围列起始列"
  endColumn : "指定范围列结束列"
  columnsToGet : "筛选列，string[],只对属性列起作用"
  transactionId : "不知道"






module.exports = exports = router